print("加载Uart_Task.lua！")
module(..., package.seeall)
require "global"
local rdbuf = ""

local function bin2hex(s)
    s =
        string.gsub(
            s,
            "(.)",
            function(x)
                return string.format("%02X ", string.byte(x))
            end
    )
    return s
end
--查询模块存活
local function cmd_0x00_proc()
    sys.publish("MQ_CMD_0x00")
end
--查询联网状态
local function cmd_0x01_proc()
    sys.publish("MQ_CMD_0x01")
end
--查询IMEI
local function cmd_0x02_proc()
    sys.publish("MQ_CMD_0x02")
end
--查询信号强度
local function cmd_0x03_proc()
    sys.publish("MQ_CMD_0x03")
end
--发布数据指令
local function cmd_0x11_proc(d_payload)
    sys.publish("MQ_CMD_0x11", d_payload)
end
--大文件接受应答
local function cmd_0x13_proc(d_payload)
    sys.publish("MQ_CMD_0x13", d_payload)
end
--RRPC指令应答
local function uartStop()
    print("1111111111111111111111")
    _G.SYS_BUSY = 1
    sys.wait(3000)
    _G.SYS_BUSY = 0
    print("2222222222222222222222")
end
local function cmd_0x15_proc(d_payload, msg_id)
    sys.taskInit(uartStop)
    sys.publish("MQ_CMD_0x15", d_payload, msg_id)
end
local function proc_data(d_cmd, d_len, d_payload, d_msg_id)
    print("准备发消息给相应处理程序")
    print("命令字:", string.format("%02x", d_cmd), "！")
    print("数据体长度:", d_len, "字节！")
    if #d_payload > 0 then
        print("数据体:", bin2hex(d_payload), "！")
    end
    if d_cmd == 0 then
        --查询模块存活
        cmd_0x00_proc()
    end
    if d_cmd == 1 then
        --查询模块联网状态
        cmd_0x01_proc()
    end
    if d_cmd == 2 then
        --查询IMEI
        cmd_0x02_proc()
    end
    if d_cmd == 3 then
        --查询信号强度
        cmd_0x03_proc()
    end
    if d_cmd == 0x11 then
        --MCU发布数据指令
        cmd_0x11_proc(d_payload)
    end
    if d_cmd == 0x13 then
        --大文件接受应答
        cmd_0x13_proc(d_payload)
    end
    if d_cmd == 0x15 then
        --大文件接受应答
        cmd_0x15_proc(d_payload, d_msg_id)
    end
end

local function parse(data)
    if not data then
        print("需要解析的数据长度为0！")
        return
    end
    
    local tail = string.find(data, string.char(_G.CMD_HEAD1) .. string.char(_G.CMD_HEAD2))
    if not tail then
        print("没有找到帧头", "！")
        return false, data
    end
    print("找到帧头了", "！")
    local tmpstr = string.sub(data, tail + _G.CMD_HEAD_LEN)
    --数据去头
    if not tmpstr or tmpstr == "" or string.len(tmpstr) < 1 then
        print("数据中只有头，后面的数据还没收到", "！")
        return false, data
    end
    if string.len(tmpstr) < (_G.CMD_VER_LEN + _G.CMD_PAYLOAD_SIZE_LEN + _G.CMD_ADD8_LEN) then
        print("数据不够，版本+长度+校验最少4个字节，当前长度为", string.len(tmpstr), "！")
        return false, data
    end
    
    if string.byte(tmpstr, _G.CMD_VER_OFFSET) ~= _G.CMD_VERSION then
        print("版本位置不对，数据是：", string.format("%02x", string.byte(tmpstr, 1)), "！")
        print("这种情况说明可能发生了数据混乱，丢弃帧头55AA", "！")
        local cutstr = string.sub(data, tail + _G.CMD_HEAD_LEN)
        print("版本校验错误，切割数据，剩余的数据是", bin2hex(cutstr), "！")
        return true, cutstr
    end
    
    local data_cmd = string.byte(tmpstr, _G.CMD_CMD_TYPE_OFFSET)
    
    local offset_cmd_arg = 0
    local msg_id = ""
    if data_cmd == 0x15 then
        print("发现RRPC指令！")
        if
            string.len(tmpstr) <
            _G.CMD_VER_LEN + _G.CMD_CMD_TYPE_LEN + _G.CMD_MSG_ID_LEN + _G.CMD_PAYLOAD_SIZE_LEN + _G.CMD_ADD8_LEN
        then
            print("RRPC数据体指令长度不够，没有传递完", "！")
            return false, data
        end
        offset_cmd_arg = _G.CMD_MSG_ID_LEN --rrpc包的 msg_id 长度
    end
    print("指令参数长度是：", offset_cmd_arg, "！")
    local data_len =
        string.byte(tmpstr, _G.CMD_PAYLOAD_SIZE_OFFSET + offset_cmd_arg) * 256 +
        string.byte(tmpstr, _G.CMD_PAYLOAD_SIZE_OFFSET + offset_cmd_arg + 1)
    print("数据体长度是：", string.format("%d字节", data_len), "！")
    
    if data_len > 512 then
        print("数据长度超过了512byte", data_len, "！")
        print("这种情况说明可能发生了数据混乱，丢弃帧头55AA", "！")
        local cutstr = string.sub(data, tail + _G.CMD_HEAD_LEN)
        print("数据长度超出，切割数据，剩余的数据是", bin2hex(cutstr), "！")
        return true, cutstr
    end
    
    local tmpstr =
        string.sub(tmpstr, _G.CMD_VER_LEN + _G.CMD_CMD_TYPE_LEN + offset_cmd_arg + _G.CMD_PAYLOAD_SIZE_LEN + 1)
    print("剩余的部分是", bin2hex(tmpstr), "！")
    
    if string.len(tmpstr) < data_len + _G.CMD_ADD8_LEN then
        print("数据体的长度不够，没有传递完", "！")
        return false, data
    end
    
    local payload = string.sub(tmpstr, 0, data_len)
    print("数据体是", bin2hex(payload), "！")
    print("开始校验", "！")
    print("传递过来的效验码是", string.format("%02x", string.byte(tmpstr, data_len + 1)), "！")
    local sum = 0
    for i = 0, data_len +
    (_G.CMD_HEAD_LEN + _G.CMD_VER_LEN + _G.CMD_CMD_TYPE_LEN + offset_cmd_arg + _G.CMD_PAYLOAD_SIZE_LEN - 1) do
        sum = sum + string.byte(data, tail + i)
    --为什么有tail而不是从0开始，因为55AA不是的是整个data的最开头
    end
    local check_code = sum % 256
    print("计算后的校验码是:", string.format("%02x", check_code), "！")
    
    if string.byte(tmpstr, data_len + 1) ~= check_code then
        print(
            "校验码不符合",
            string.format("%02x", string.byte(tmpstr, data_len + 1)),
            "<>",
            string.format("%02x", check_code),
            "！"
        )
        print("这种情况说明可能发生了数据混乱，丢弃帧头和数据体", "！")
        local cutstr =
            string.sub(
                data,
                tail + _G.CMD_HEAD_LEN + _G.CMD_VER_LEN + _G.CMD_CMD_TYPE_LEN + offset_cmd_arg + _G.CMD_PAYLOAD_SIZE_LEN +
                data_len
        )
        print("版本校验错误，切割数据，剩余的数据是", bin2hex(cutstr), "！")
        return true, cutstr
    end
    
    print("指令校验成功", "！")
    local d_cmd = data_cmd
    local d_len = data_len
    local d_payload = payload
    local d_msg_id = string.sub(data, 
    tail + _G.CMD_HEAD_LEN + _G.CMD_VER_LEN + _G.CMD_CMD_TYPE_LEN, 
    tail + _G.CMD_HEAD_LEN + _G.CMD_VER_LEN + _G.CMD_CMD_TYPE_LEN + _G.CMD_MSG_ID_LEN - 1)
    
    if data_cmd == 0x15 then
        print("********************************************")
        print("rrpc msgID=",d_msg_id)
        print("********************************************")
    end
    
    proc_data(d_cmd, d_len, d_payload, d_msg_id)
    
    print(
        bin2hex(
            string.sub(
                data,
                tail + _G.CMD_HEAD_LEN + _G.CMD_VER_LEN + _G.CMD_CMD_TYPE_LEN + offset_cmd_arg + _G.CMD_PAYLOAD_SIZE_LEN +
                data_len +
                1
    )
    )
    )
    local newdata =
        string.sub(
            data,
            tail + _G.CMD_HEAD_LEN + _G.CMD_VER_LEN + _G.CMD_CMD_TYPE_LEN + offset_cmd_arg + _G.CMD_PAYLOAD_SIZE_LEN +
            data_len +
            1
    )
    return true, newdata
end

local function proc(data)
    if not data or string.len(data) == 0 then
        return
    end
    
    rdbuf = rdbuf .. data
    
    local result, unproc
    unproc = rdbuf
    
    if _G.SYS_BUSY == 1 then
        print("************系统忙","！")
        --直接返回，串口收到的数据累加到rdbuf中，以后再处理
        return
    end

    while true do  
        result, unproc = parse(unproc)
        print("解析结果", result, bin2hex(unproc), "！")
        if not unproc or unproc == "" or not result then
            break
        end
    end
    
    rdbuf = unproc or ""
    print("新的rdbuf是", bin2hex(rdbuf), "！")
end

local function read()
    local data = ""
 

    while true do
        data = uart.read(_G.UART_ID, "*l")
        if not data or string.len(data) == 0 then
            break
        end
        
        log.info("testUart.read hex", data:toHex())
        proc(data)
    end
end

uart.on(_G.UART_ID, "receive", read)

uart.setup(_G.UART_ID, _G.UART_BAUD, 8, uart.PAR_NONE, uart.STOP_1)
